﻿// ***********************************************************************
// Assembly         : Invisionware.API.Amazon
// Author           : Shawn Anderson (sanderson@eye-catcher.com)
// Created          : 01-10-2014
//
// Last Modified By : Shawn Anderson
// Last Modified On : 01-19-2014
// ***********************************************************************
// <copyright file="ItemDataTypes.cs" company="Invisionware">
//     Copyright (c) Invisionware. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************

using System;
using System.Collections.Generic;
using System.Linq;

namespace Invisionware.API.Amazon
{
	/// <summary>
	/// Class DictionaryExtensions.
	/// </summary>
	public static class DictionaryExtensions
	{
		/// <summary>
		/// Merges the specified primary.
		/// </summary>
		/// <typeparam name="TKey">The type of the t key.</typeparam>
		/// <typeparam name="TValue">The type of the t value.</typeparam>
		/// <param name="primary">The primary.</param>
		/// <param name="secondary">The secondary.</param>
		/// <returns>IDictionary{``0``1}.</returns>
		public static IDictionary<TKey, TValue> Merge<TKey, TValue>(this IDictionary<TKey, TValue> primary,
			IDictionary<TKey, TValue> secondary)
		{
			return Merge(new List<IDictionary<TKey, TValue>> { primary, secondary }, null);
		}

		/// <summary>
		/// Merges the specified primary.
		/// </summary>
		/// <typeparam name="TKey">The type of the t key.</typeparam>
		/// <typeparam name="TValue">The type of the t value.</typeparam>
		/// <param name="primary">The primary.</param>
		/// <param name="secondary">The secondary.</param>
		/// <param name="resolveDuplicates">The resolve duplicates.</param>
		/// <returns>IDictionary{``0``1}.</returns>
		public static IDictionary<TKey, TValue> Merge<TKey, TValue>(this IDictionary<TKey, TValue> primary,
			IDictionary<TKey, TValue> secondary, Func<IGrouping<TKey, TValue>, TValue> resolveDuplicates)
		{
			return Merge(new List<IDictionary<TKey, TValue>> { primary, secondary }, resolveDuplicates);
		}

		/// <summary>
		/// Merges the specified dicts.
		/// </summary>
		/// <typeparam name="TKey">The type of the t key.</typeparam>
		/// <typeparam name="TValue">The type of the t value.</typeparam>
		/// <param name="dicts">The dicts.</param>
		/// <returns>IDictionary{``0``1}.</returns>
		public static IDictionary<TKey, TValue> Merge<TKey, TValue>(this IEnumerable<IDictionary<TKey, TValue>> dicts)
		{
			return Merge(dicts, null);
		}

		/// <summary>
		/// Merges the specified dicts.
		/// </summary>
		/// <typeparam name="TKey">The type of the t key.</typeparam>
		/// <typeparam name="TValue">The type of the t value.</typeparam>
		/// <param name="dicts">The dicts.</param>
		/// <param name="resolveDuplicates">The resolve duplicates.</param>
		/// <returns>IDictionary{``0``1}.</returns>
		public static IDictionary<TKey, TValue> Merge<TKey, TValue>(this IEnumerable<IDictionary<TKey, TValue>> dicts,
			Func<IGrouping<TKey, TValue>, TValue> resolveDuplicates)
		{
			if (resolveDuplicates == null)
			{
				resolveDuplicates = group => @group.First();
			}

			return dicts.SelectMany(dict => dict)
				.ToLookup(pair => pair.Key, pair => pair.Value)
				.ToDictionary(group => group.Key, group => resolveDuplicates(group));
		}
	}
}
